home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / cross / GBDK-2.0.lha / GBDK / lib / malloc.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  3KB  |  112 lines

  1. #include <sys/malloc.h>
  2. #include <stdio.h>
  3.  
  4. pmmalloc_hunk malloc_first;
  5.  
  6. void debug( char *fun, char *msg )
  7. {
  8. /*    return; */
  9. /*    printf("%s: %s\n", fun, msg );*/
  10. }
  11.  
  12. BYTE malloc_init(void)
  13. {
  14.     if (malloc_first->magic!=MALLOC_MAGIC) {
  15.         /* Init by setting up the first hunk */
  16.  
  17.         debug("malloc_init", "Setting up");
  18.         malloc_first = (pmmalloc_hunk)&malloc_heap_start;
  19.  
  20.         malloc_first->next = NULL;
  21.         malloc_first->size = 0xDFFFU - 0x200 - sizeof(mmalloc_hunk) - (UWORD)&malloc_heap_start;
  22.         malloc_first->status = MALLOC_FREE;
  23.  
  24.         malloc_first->magic = MALLOC_MAGIC;
  25.         return 0;
  26.     }
  27.     return -1;
  28. }
  29.  
  30. void malloc_gc(void)
  31. {
  32.     /* Do a garbage collect on the hunks to create bigger hunks */
  33.     /* Note: assumes that hunks are consecutive */
  34.  
  35.     pmmalloc_hunk thisHunk, nextHunk;
  36.     UBYTE changed;
  37.  
  38.     changed = 1;
  39.  
  40.     debug("malloc_gc","Running");
  41.     while (changed) {
  42.         thisHunk = malloc_first;
  43.         changed = 0;
  44.         while (thisHunk && (thisHunk->magic==MALLOC_MAGIC)) {
  45.             if (thisHunk->status == MALLOC_FREE) {
  46.                 nextHunk = thisHunk->next;
  47.                 if (nextHunk->status == MALLOC_FREE) {
  48.                     /* Must be consecutive */
  49.                     changed = 1;
  50.                     thisHunk->size+=nextHunk->size+sizeof(mmalloc_hunk);
  51.                     thisHunk->next = nextHunk->next;
  52.                 }
  53.             }
  54.             thisHunk=thisHunk->next;
  55.         }
  56.         if (thisHunk!=NULL)
  57.             debug("malloc_gc", "Corrupted malloc list found.");
  58.     }
  59. }
  60.         
  61. void *malloc( UWORD size )
  62. {
  63.     pmmalloc_hunk thisHunk, insertBefore;
  64.     pmmalloc_hunk newHunk;
  65.     UBYTE firstTry;
  66.  
  67.     if (malloc_first->magic != MALLOC_MAGIC)
  68.         malloc_init();
  69.  
  70.     firstTry = 1;    /* Allows gc if no big enough hunk is found */
  71.     
  72.     while (firstTry) {
  73.         thisHunk = malloc_first;
  74.         if (firstTry == 2)
  75.             firstTry = 0;
  76.  
  77.         while (thisHunk&&(thisHunk->magic == MALLOC_MAGIC)) {
  78.             debug("malloc", "Entering hunk" );
  79.             if (thisHunk->status == MALLOC_FREE) {
  80.                 debug("malloc", "Found free hunk" );
  81.  
  82.                 /* Free, is it big enough? */
  83.                 if (thisHunk->size >= size+sizeof(mmalloc_hunk)) {
  84.                     
  85.                     debug("malloc","Found a big enough hunk.");
  86.                     
  87.                     /* Yes, big enough */
  88.                     insertBefore = thisHunk->next;
  89.                     newHunk = (pmmalloc_hunk)((UWORD)thisHunk + size + sizeof(mmalloc_hunk));
  90.                     newHunk->size = thisHunk->size - sizeof(mmalloc_hunk) - size;
  91.                     newHunk->status = MALLOC_FREE;
  92.                     newHunk->next = insertBefore;
  93.                     newHunk->magic = MALLOC_MAGIC;
  94.                     
  95.                     thisHunk->size = size;
  96.                     thisHunk->status = MALLOC_USED;
  97.                     thisHunk->next = newHunk;
  98.                     
  99.                     return (void *)((UWORD)thisHunk + sizeof(mmalloc_hunk));
  100.                 }
  101.             }
  102.             thisHunk = thisHunk->next;
  103.         }
  104.         if (firstTry) {
  105.             /* Try again after a garbage collect */
  106.             malloc_gc();
  107.             firstTry = 2;
  108.         }
  109.     }
  110.     return NULL;
  111. }
  112.